package com.beiben.system.user.service.impl;

import com.beiben.ability.people.domain.TreeSelectDept;
import com.beiben.system.group.domain.UserGroup;
import com.beiben.system.group.mapper.UserGroupMapper;
import com.beiben.system.hours.domain.UserHours;
import com.beiben.system.hours.mapper.UserHoursMapper;
import com.beiben.system.user.domain.*;
import com.beiben.system.user.mapper.BeiBenUserMapper;
import com.beiben.system.user.service.IBeiBenUserService;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysPost;
import com.ruoyi.system.domain.SysUserPost;
import com.ruoyi.system.domain.SysUserRole;
import com.ruoyi.system.mapper.SysPostMapper;
import com.ruoyi.system.mapper.SysRoleMapper;
import com.ruoyi.system.mapper.SysUserPostMapper;
import com.ruoyi.system.mapper.SysUserRoleMapper;
import com.ruoyi.system.service.ISysConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by admin on 2020/8/25.
 */
@Service
public class BeiBenUserServiceImpl implements IBeiBenUserService {

    private static final Logger log = LoggerFactory.getLogger(BeiBenUserServiceImpl.class);

    @Autowired
    private BeiBenUserMapper beiBenUserMapper;

    @Autowired
    private SysRoleMapper roleMapper;

    @Autowired
    private SysPostMapper postMapper;

    @Autowired
    private SysUserRoleMapper userRoleMapper;

    @Autowired
    private SysUserPostMapper userPostMapper;

    @Autowired
    private ISysConfigService configService;

    @Autowired
    private UserHoursMapper userHoursMapper;

    @Autowired
    private UserGroupMapper userGroupMapper;


    /**
     * 根据条件分页查询用户列表
     *
     * @param user 用户信息
     * @return 用户信息集合信息
     */
    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public List<BeiBenUser> selectBeiBenUserList(BeiBenUser user)
    {
        return beiBenUserMapper.selectBeiBenUserList(user);
    }

    @Override
    public BeiBenUser selectUserById(Long userId) {
        return beiBenUserMapper.selectUserById(userId);
    }

    /**
     * 构建前端所需要下拉树结构
     *
     * @param deptId 部门列表id
     * @return 下拉树结构列表
     */
    @Override
    public List<TreeSelectDept> buildDeptTreeSelect(Long deptId) {
        List<BeiBenDeptUser> deptTrees = new ArrayList<BeiBenDeptUser>();
        List<BeiBenDeptUser> depts = beiBenUserMapper.selectDeptById(deptId);
        List<Long> deptIds = new ArrayList<>();
        for (SysDept dept : depts) {
            deptIds.add(dept.getDeptId());
        }
        //3. 获取人员列表：按部门id 获取 部门下所有部门人员
        List<ExamUser> users = beiBenUserMapper.selectUserByDeptIds(deptIds);
        //4. 提取Map：key(dept_id) value(userInfo)
        Map<Long, List<BeiBenUser>> userMap = new HashMap<>();
        for (ExamUser user : users) {
            if (userMap.get(user.getDeptId()) != null) {
                List<BeiBenUser> beiBenUsers = userMap.get(user.getDeptId());
                beiBenUsers.add(user);
            } else {
                List<BeiBenUser> beiBenUsers = new ArrayList<>();
                beiBenUsers.add(user);
                userMap.put(user.getDeptId(), beiBenUsers);
            }
        }

        for (Iterator<BeiBenDeptUser> iterator = depts.iterator(); iterator.hasNext(); ) {
            BeiBenDeptUser dept = (BeiBenDeptUser) iterator.next();
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!deptIds.contains(dept.getParentId())) {
                recursionFn(depts, dept, userMap);
                deptTrees.add(dept);
            }
        }
        if (deptTrees.isEmpty()) {
            deptTrees = depts;
        }
        return deptTrees.stream().map(TreeSelectDept::new).collect(Collectors.toList());
    }

    /**
     * 部门员工信息
     * @param deptId
     * @return
     */
    @Override
    public List<BeiBenUser> getDeptUserInfo(Long deptId) {
        return beiBenUserMapper.getDeptUserInfo(deptId);
    }

    @Override
    public int insertBeiBenUser(BeiBenUser user) {
        // 新增用户信息
        int rows = beiBenUserMapper.insertBeiBenUser(user);
        // 新增工时关联
        insertUserHours(user);
        // 新增用户岗位关联
        insertUserPost(user);
        // 新增用户与角色管理
        insertUserRole(user);
        // 新增组别管理
        insertUserGroups(user);
        return rows;
    }


    /**
     * 修改保存用户信息
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    @Transactional
    public int updateBeiBenUser(BeiBenUser user)
    {
        Long userId = user.getUserId();
        // 删除用户与角色关联
        userRoleMapper.deleteUserRoleByUserId(userId);
        // 新增用户与角色管理
        insertUserRole(user);
        // 删除用户与岗位关联
        userPostMapper.deleteUserPostByUserId(userId);
        // 新增用户与岗位管理
        insertUserPost(user);
        // 删除用户与组别关联
        userGroupMapper.deleteUserGroupById(userId);
        // 新增组别管理
        insertUserGroups(user);
        return beiBenUserMapper.updateBeiBenUser(user);
    }
    /**
     * 校验用户是否允许操作
     *
     * @param user 用户信息
     */
    @Override
    public void checkUserAllowed(BeiBenUser user) {
        if (StringUtils.isNotNull(user.getUserId()) && user.isAdmin())
        {
            throw new CustomException("不允许操作超级管理员用户");
        }
    }


    public void insertUserHours(BeiBenUser user){
        UserHours userHours = new UserHours();
        userHours.setUserId(user.getUserId());
        userHours.setHoursId(Long.valueOf(user.getHoursIds()));
        userHoursMapper.insertUserHours(userHours);
    }

    public void insertUserGroups(BeiBenUser user){
        Long[] groupIds = user.getGroupTypeIds();
        if (StringUtils.isNotNull(groupIds))
        {
            // 新增用户与岗位管理
            List<UserGroup> list = new ArrayList<UserGroup>();
            for (Long groupId : groupIds)
            {
                UserGroup ug = new UserGroup();
                ug.setUserId(user.getUserId());
                ug.setGroupId(groupId);
                list.add(ug);
            }
            if (list.size() > 0)
            {
                userGroupMapper.batchUserGroup(list);
            }
        }
    }

    /**
     * 新增用户岗位信息
     *
     * @param user 用户对象
     */
    public void insertUserPost(BeiBenUser user)
    {
        Long[] posts = user.getPostIds();
        if (StringUtils.isNotNull(posts))
        {
            // 新增用户与岗位管理
            List<SysUserPost> list = new ArrayList<SysUserPost>();
            for (Long postId : posts)
            {
                SysUserPost up = new SysUserPost();
                up.setUserId(user.getUserId());
                up.setPostId(postId);
                list.add(up);
            }
            if (list.size() > 0)
            {
                userPostMapper.batchUserPost(list);
            }
        }
    }

    /**
     * 新增用户角色信息
     *
     * @param user 用户对象
     */
    public void insertUserRole(BeiBenUser user)
    {
        Long[] roles = user.getRoleIds();
        if (StringUtils.isNotNull(roles))
        {
            // 新增用户与角色管理
            List<SysUserRole> list = new ArrayList<SysUserRole>();
            for (Long roleId : roles)
            {
                SysUserRole ur = new SysUserRole();
                ur.setUserId(user.getUserId());
                ur.setRoleId(roleId);
                list.add(ur);
            }
            if (list.size() > 0)
            {
                userRoleMapper.batchUserRole(list);
            }
        }
    }

    /**
     * 递归列表
     */
    private void recursionFn(List<BeiBenDeptUser> list, BeiBenDeptUser t, Map<Long, List<BeiBenUser>> userMap) {
        // 得到子节点列表
        List<BeiBenDeptUser> childList = getChildList(list, t);
        t.setDepts(childList);
        List<BeiBenUser> beiBenUsers = userMap.get(t.getDeptId());
        if (beiBenUsers == null) {
            beiBenUsers = new ArrayList<>();
        }
        t.setUsers(beiBenUsers);
        for (BeiBenDeptUser tChild : childList) {
            if (hasChild(list, tChild)) {
                // 判断是否有子节点
                Iterator<BeiBenDeptUser> it = childList.iterator();
                while (it.hasNext()) {
                    BeiBenDeptUser n = (BeiBenDeptUser) it.next();
                    recursionFn(list, n, userMap);
                }
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<BeiBenDeptUser> getChildList(List<BeiBenDeptUser> list, SysDept t) {
        List<BeiBenDeptUser> tlist = new ArrayList<BeiBenDeptUser>();
        Iterator<BeiBenDeptUser> it = list.iterator();
        while (it.hasNext()) {
            BeiBenDeptUser n = (BeiBenDeptUser) it.next();
            if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getDeptId().longValue()) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<BeiBenDeptUser> list, SysDept t) {
        return getChildList(list, t).size() > 0 ? true : false;
    }

    @Override
    public List<TreeSelectVo> buildUserTreeSelect(long deptId) {
        List<TreeSelectVo>  deptList =  beiBenUserMapper.selectDeptTreeData(deptId);
        List<TreeSelectVo>  userList = beiBenUserMapper.selectUserTreeData(deptId);
        //   生成树结构
        List<TreeSelectVo> deptTreeList = buildDeptTree(deptList);
        List<TreeSelectVo> userTreeList = recursionDuFn(deptTreeList,userList);
        return userTreeList;
    }

    @Override
    public List<SysPost> selectUserPostByUserId(Long userId) {
        return beiBenUserMapper.selectUserPostByUserId(userId);
    }


    /**
     * 添加用户数据
     */
    private List<TreeSelectVo> recursionDuFn(List<TreeSelectVo> deptTress,List<TreeSelectVo> userList)
    {
        for(TreeSelectVo user : userList){
            dg(deptTress,user);
        }
        return deptTress;
    }

    /*
    * 递归增加用户数据
     *  */
    public void dg(List<TreeSelectVo> deptTress,TreeSelectVo user){
        for(TreeSelectVo dept : deptTress){
            if(dept.getType().equals("0")){
                if(!dept.getId().contains("-")){
                    dept.setId(dept.getId() + "-" + dept.getType());
                }
                if(user.getParentId().equals(dept.getId().substring(0,dept.getId().indexOf("-")))){
                    List<TreeSelectVo> chlid =  dept.getChildren();
                    chlid.add(user);
                    dept.setChildren(chlid);
                }
            }
            if(dept.getChildren().size()>0){
                dg(dept.getChildren(),user);
            }
        }
    }

    /**
     * 构建前端所需要树结构
     *
     * @param trees 部门列表
     * @return 树结构列表
     */
    public List<TreeSelectVo> buildDeptTree(List<TreeSelectVo> trees)
    {
        List<TreeSelectVo> returnList = new ArrayList<TreeSelectVo>();
        List<String> tempList = new ArrayList<>();
        for (TreeSelectVo tree : trees)
        {
            tempList.add(tree.getId());
        }
        for (Iterator<TreeSelectVo> iterator = trees.iterator(); iterator.hasNext();)
        {
            TreeSelectVo tree = (TreeSelectVo) iterator.next();
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(tree.getParentId()))
            {
                recursionUserFn(trees, tree);
                returnList.add(tree);
            }
        }
        if (returnList.isEmpty())
        {
            returnList = trees;
        }
        return returnList;
    }
    /**
     * 递归列表
     */
    private void recursionUserFn(List<TreeSelectVo> list, TreeSelectVo t)
    {
        // 得到子节点列表
        List<TreeSelectVo> childList = getChildUserList(list, t);
        t.setChildren(childList);
        for (TreeSelectVo tChild : childList)
        {
            if (hasUserChild(list, tChild))
            {
                recursionUserFn(list, tChild);
            }
        }
    }
    /**
     * 得到子节点列表
     */
    private List<TreeSelectVo> getChildUserList(List<TreeSelectVo> list, TreeSelectVo t)
    {
        List<TreeSelectVo> tlist = new ArrayList<TreeSelectVo>();
        Iterator<TreeSelectVo> it = list.iterator();
        while (it.hasNext())
        {
            TreeSelectVo n = (TreeSelectVo) it.next();
            if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().equals(t.getId()))
            {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasUserChild(List<TreeSelectVo> list, TreeSelectVo t)
    {
        return getChildUserList(list, t).size() > 0 ? true : false;
    }
}
